package io.gitee.macxiang.sql;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.reflections.Reflections;
import org.reflections.scanners.Scanners;
import org.reflections.util.ConfigurationBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.stereotype.Component;

import io.gitee.macxiang.annotation.EntityScan;
import io.gitee.macxiang.annotation.Reader;
import io.gitee.macxiang.annotation.TableName;
import io.gitee.macxiang.entity.PathCode;
import io.gitee.macxiang.utils.utils;

/** 扫描实体类 */
@Component
public class EntityScanRegistrar implements ImportBeanDefinitionRegistrar {
  @Override
  public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    // utils.clear();
    String name = EntityScan.class.getName();
    Map<String, Object> map = importingClassMetadata.getAnnotationAttributes(name);
    if (map != null) {
      // 获取 @EntityScan 注解的 basePackages 属性
      String[] basePackages = (String[]) map.get("basePackages");
      if (basePackages != null && basePackages.length > 0) {
        // 扫描指定的包
        for (String packageName : basePackages) {
          // 创建 Reflections 实例
          Reflections reflections = new Reflections(new ConfigurationBuilder()
              .forPackages(packageName)
              .addScanners(Scanners.TypesAnnotated));
          // 查找所有带有 TableName 注解的类
          Set<Class<?>> annotatedClasses = reflections.getTypesAnnotatedWith(TableName.class);
          StringBuilder sb = new StringBuilder();
          List<PathCode> pc = new ArrayList<>();
          String pa = null, ps = "";
          // 输出结果
          if (!annotatedClasses.isEmpty()) {
            final List<Class<?>> clazzs = new ArrayList<>(annotatedClasses);
            for (Class<?> clazz : clazzs) {
              utils.controller.addServiceName(Reader.getClassNameFull(clazz));
            }
            if (Reader.isRelease(clazzs.get(0))) {
              return;
            }
            for (Class<?> clazz : clazzs) {
              try {
                Reader.genAuto(clazz, sb, pc);
              } catch (Exception e) {
                System.err.println(utils.errString(e));
                return;
              }
              final String pathRoot = Reader.getPathRoot(clazz);
              if (pathRoot == null) {
                return;
              }
              final String packageService = Reader.getPackageService(clazz),
                  pathAuto = Reader.getPathAuto(pathRoot, packageService);
              if (pa == null) {
                pa = pathAuto;
                ps = packageService;
              }
              if (!pa.equals(pathAuto)) {
                Reader.writeAuto(pa, ps, sb);
                pa = pathAuto;
                ps = packageService;
              }

            }
            Reader.writeAuto(pa, ps, sb);
            if (pc.size() > 0) {
              pc.forEach(e -> {
                utils.writeFile(e.path, e.code);
              });
            }
          }
        }
      }
    }

  }
}
